// Remember some divs for easy reference later.
var participantsDiv = document.getElementById('participants');
var whosTalkin = document.getElementById('whosTalkin');
var orchestratorToggleButton = document.getElementById('orchestratorToggleButton');

// What ID has the highlight right now?
var currentHighlightedParticipantId = null;

// Object via which the HTTP requests are submitted to the server
var xmlHttpReq = getXmlHttpRequestObject();

// The URL of the Orchestrator engine
var serverUrl = "http://ma121.gold.ac.uk/video-orch/";

// Indicates whether the orchestrator is turned on or off
var orchestratorFlag = false;


function getDisplayNameFromId(id) {
  var participant = gapi.hangout.getParticipantById(id);
  if (!participant || !participant.hasAppEnabled) {
    return 'An unknown person';
  }
  return participant.person.displayName;
}

// Updates div to say who is shown in the video canvas
function updateDisplayedParticipant() {
  if (currentHighlightedParticipantId) {
    whosTalkin.innerHTML = '<p>Locked to ' +
        getDisplayNameFromId(currentHighlightedParticipantId) + '</p>';
    //TODO bla
    //submitXmlHttpReq(serverUrl + "Hello?currentParticipant=" + getDisplayNameFromId(currentHighlightedParticipantId), handleXmlHttpResp);
    return;
  }

  var id = gapi.hangout.layout.getDefaultVideoFeed().getDisplayedParticipant();
  whosTalkin.innerHTML = '<p>Currently ' +
      getDisplayNameFromId(id) + '</p>';
}

// Shows a list of participants with clickable buttons to lock them
function updateParticipants() {
  var retVal = '<ul>';

  var participants = gapi.hangout.getParticipants();

  for (var index in participants) {
    var part = participants[index];

    retVal += '<li>' + getDisplayNameFromId(part.id) +
        ' <input type="button" value="Lock" id="lockMeButton"' +
            'onClick="lockParticipant(\'' + part.id + '\')"/></li>';
  }

  retVal += '</ul>';

  // Check to see if the current participant
  if (currentHighlightedParticipantId &&
      !gapi.hangout.getParticipantById(currentHighlightedParticipantId)) {
    currentHighlightedParticipantId = null;
    showDefaultFeed();
  }

  participantsDiv.innerHTML = retVal;
}

// Displays the video feed that would normally be
// visible if the app.  The DefaultVideoFeed generally
// shows feeds based on their volume level.
function showDefaultFeed() {

  // Remove the highlighting.
  if (currentHighlightedParticipantId) {
    gapi.hangout.av.clearAvatar(currentHighlightedParticipantId);
  }

  currentHighlightedParticipantId = null;

  var feed = gapi.hangout.layout.getDefaultVideoFeed();
  var canvas = gapi.hangout.layout.getVideoCanvas();

  canvas.setVideoFeed(feed);
  canvas.setWidth(600);
  canvas.setPosition(300, 50);
  canvas.setVisible(true);

  // Update the text
  updateDisplayedParticipant();
}

// Displays the video feed for a given participant
function lockParticipant(partId) {

  // Remove any previous highlighting.
  if (currentHighlightedParticipantId) {
    gapi.hangout.av.clearAvatar(currentHighlightedParticipantId);
  }

  // Remember who is selected
  currentHighlightedParticipantId = partId;
  // Highlight this user with the red rectangle.
  gapi.hangout.av.setAvatar(currentHighlightedParticipantId,
      'http://mediakit001.appspot.com/static/images/participantHighlight.png');

  // Set the feed
  var feed = gapi.hangout.layout.createParticipantVideoFeed(partId);
  var canvas = gapi.hangout.layout.getVideoCanvas();

  canvas.setVideoFeed(feed);
  canvas.setWidth(600);
  canvas.setPosition(300, 50);
  canvas.setVisible(true);

  // Update the text
  updateDisplayedParticipant();
}


//Gets the browser specific XmlHttpRequest Object
function getXmlHttpRequestObject() {
	if (window.XMLHttpRequest) {
		return new XMLHttpRequest();
	} else if(window.ActiveXObject) {
		return new ActiveXObject("Microsoft.XMLHTTP");
	} else {
		console.log('Status: Cound not create XmlHttpRequest Object. Consider upgrading your browser.');
	}
}

function submitXmlHttpReq(url, handler) {
	if (xmlHttpReq.readyState == 4 || xmlHttpReq.readyState == 0) {
		xmlHttpReq.open("GET", url, true);
		xmlHttpReq.onreadystatechange = handler; 
		xmlHttpReq.send(null);
	}				
}

function handleCutXmlHttpResp() {
	// Handle the async response to submitXmlHttpReq(serverUrl + "cut?...")
	if (xmlHttpReq.readyState == 4) {
		try {
			var response = eval("(" + xmlHttpReq.responseText + ")");
			if ( response.cutTo !== undefined ) {
				console.log("Cut command received [cutTo = " + response.cutTo + "]");
				// Execute the cutTo --> set the feed
				var feed = gapi.hangout.layout.createParticipantVideoFeed(response.cutTo);
				var canvas = gapi.hangout.layout.getVideoCanvas();
				
				canvas.setVideoFeed(feed);
				canvas.setWidth(600);
				canvas.setPosition(300, 50);
				canvas.setVisible(true);				
			} else {
				console.log("No cut command received.");
			}

			// Poll for next cut 
			if ( orchestratorFlag !== undefined && orchestratorFlag ) {
				console.log("Poll for next cut.");
				submitXmlHttpReq(serverUrl + "cut?hangoutUrl=" + gapi.hangout.getHangoutUrl() + 
						"&participantId=" + gapi.hangout.getParticipantId(), handleCutXmlHttpResp);				
			}			
		} catch ( SyntaxError ) {
			console.log("Syntax error: failed to parse JSON response [" + xmlHttpReq.responseText + "]" );
		}
	}	
}

function handleHangoutXmlHttpResp() {
	// Handle the async response to submitXmlHttpReq(serverUrl + "hangout?...")
	if (xmlHttpReq.readyState == 4) {
		try {
			var response = eval("(" + xmlHttpReq.responseText + ")");
			if ( response ) {
				console.log("handleHangoutXmlHttpResp returned");
				for ( key in response ) {
					console.log( key + " -> " + response[key]);					
				}				
			}
		} catch ( SyntaxError ) {
			console.log("Syntax error: failed to parse JSON response [" + xmlHttpReq.responseText + "]" );
		}
	}
}


// This runs when the gadget is ready
function init() {
  console.log('Init.');
  //submitXmlHttpReq(serverUrl + "Hello?init=1", handleXmlHttpResp);

  // When API is ready...
  gapi.hangout.onApiReady.add(
      function(eventObj) {
        if (eventObj.isApiReady) {
          console.log('API is ready');      
                    
          updateParticipants();
          updateDisplayedParticipant();
          
          // Add some listeners
          submitXmlHttpReq(serverUrl + "hangout?hangoutUrl=" + gapi.hangout.getHangoutUrl() + 
          		  "&participantId=" + gapi.hangout.getParticipantId() + 
          		  "&displayName=" + getDisplayNameFromId(gapi.hangout.getParticipantId()), handleHangoutXmlHttpResp);                

          // When people leave the hangout
          gapi.hangout.onParticipantsChanged.add(
              function(eventObj) {
                console.log('Participants changed');                
                updateParticipants();
              });

          // Every time the default video feed changes, we want the text to change
          // Note that these events go off whether or not the default video feed
          // is currently displayed.
          gapi.hangout.layout.getDefaultVideoFeed().onDisplayedParticipantChanged.add(
              function(eventObj) {
                console.log('Displayed participant changed');
                updateDisplayedParticipant();
              });
          
          // Enable the orchestrator toggle button
          orchestratorToggleButton.disabled = false;
         
        }
      });
}

function toggleOrchestrator() {
	console.log("Orchestrator is currently " + (orchestratorFlag ? "on" : "off") + ". It is now being turned " + (orchestratorFlag ? "off" : "on") + ".");	
	orchestratorFlag = !orchestratorFlag;
	if ( orchestratorFlag ) {
		submitXmlHttpReq(serverUrl + "cut?hangoutUrl=" + gapi.hangout.getHangoutUrl() + 
				"&participantId=" + gapi.hangout.getParticipantId(), handleCutXmlHttpResp);			
	}
	orchestratorToggleButton.value = (orchestratorFlag ? "Stop orchestrator" : "Start orchestrator");
}

// Wait for gadget to load.
gadgets.util.registerOnLoadHandler(init);
